// xcache的redis驱动实现
package xcacheredis

import (
	"context"
	"fmt"
	"time"

	"github.com/go-redis/redis/v8"
)

// redis驱动，用于基础信息存储等
type Redis struct {
	Host     string        `json:"host" ini:"host"`         // Redis主机地址
	Port     int           `json:"port" ini:"port"`         // Redis端口
	Password string        `json:"password" ini:"password"` // Redis密码
	DB       int           `json:"db" ini:"db"`             // Redis数据库
	Cli      *redis.Client `json:"-" ini:"-"`               // Redis客户端
}

// 打开redis连接
// host: Redis主机地址
// port: Redis端口
// password: Redis密码
// db: Redis数据库
func Open(host string, port int, password string, db int) *Redis {
	return &Redis{
		Host:     host,
		Port:     port,
		Password: password,
		DB:       db,
	}
}

// 获取驱动名称
func (c *Redis) Name() string {
	return "redis"
}

// 获取所有缓存key下标名称
func (c *Redis) Keys() []string {
	if c.Cli == nil {
		c.connect()
	}
	keys, err := c.Cli.Keys(context.Background(), "*").Result()
	if err != nil {
		return nil
	}
	return keys
}

// 获取redis客户端连接
func (c *Redis) GetCli() *redis.Client {
	if c.Cli == nil {
		c.connect()
	}
	return c.Cli
}

// redis连接
func (c *Redis) connect() {
	if c.Cli == nil {
		c.Cli = redis.NewClient(&redis.Options{
			Addr:     fmt.Sprintf("%s:%d", c.Host, c.Port),
			Password: c.Password,
			DB:       c.DB,
		})
	}
}

// 设置缓存项
func (c *Redis) Store(name, value string, ext time.Duration) error {
	if c.Cli == nil {
		c.connect()
	}
	return c.Cli.SetEX(context.Background(), name, value, ext).Err()
}

// 读取缓存项
func (c *Redis) Load(name string) (string, error) {
	if c.Cli == nil {
		c.connect()
	}
	inf := c.Cli.Get(context.Background(), name)
	if err := inf.Err(); err != nil {
		return "", err
	}
	return inf.Val(), nil
}

func (c *Redis) Delete(name string) error {
	if c.Cli == nil {
		c.connect()
	}
	return c.Cli.Del(context.Background(), name).Err()
}

func (c *Redis) Clear() error {
	if c.Cli == nil {
		c.connect()
	}
	return c.Cli.FlushDB(context.Background()).Err()
}
